package com.sergenis.swing;

import java.awt.Container;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Shape;
import java.awt.Window;
import java.awt.geom.RoundRectangle2D;

import javax.swing.Box.Filler;
import javax.swing.ImageIcon;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;

import com.sun.awt.AWTUtilities;

/**
 * <p>Clase para que ayuda a mostrar una imagen en la pantalla con
 * una barra de progreso que muestra la carga de informacion en tiempo real.</p>
 * <p> Exelente cuando la aplicación tarda en cargar al inicio y se quiere
 * mostrar la informacion del progreso</p>
 * @author SerGenis
 * @version 1.3
 */
public abstract class SplashDialog
    extends JDialog {

    /**
     * Constructor para inicializar la clase de SplashDialog e iniciar
     * automáticamente el hilo para cargar la información {@link startTheread()}
     */
    public SplashDialog() {
	this(true);
    }

    public SplashDialog(Window owner) {
	this(owner, true);
    }

    public SplashDialog(Dialog owner) {
	this(owner, true);
    }

    public SplashDialog(Frame owner) {
	this(owner, true);
    }

    /**
     * Constructor para inicializar la clase de SplashDialog decidiendo si
     * deseamos que el hilo de carga se inicie automáticamente.
     * @param autoStart Indica si queremos que el hilo se inicie automáticamente.
     */
    public SplashDialog(boolean autoStart) {
	super();
	initConstrutor(autoStart);
    }

    public SplashDialog(Window owner, boolean autoStart) {
	super(owner);
	initConstrutor(autoStart);
    }

    public SplashDialog(Dialog owner, boolean autoStart) {
	super(owner);
	initConstrutor(autoStart);
    }

    public SplashDialog(Frame owner, boolean autoStart) {
	super(owner);
	initConstrutor(autoStart);
    }

    private final void initConstrutor(boolean autoStart) {
	// Este metodo hace que el frame no tenga los
	// bordes y la barra de titulo.
	setUndecorated(true);
	initComponents();
	Shape shape = new RoundRectangle2D.Float(0, 0,
	    getWidth(), getHeight(), 25, 25);
	AWTUtilities.setWindowShape(this, shape);
	AWTUtilities.setWindowOpacity(this, 0.9F);
	if (autoStart) startThread();
    }

    private void initComponents() {
	this.label = new JLabel();
	this.progressBar = new JProgressBar(0, 100);
	Filler filler = new Filler(new Dimension(0, 0), new Dimension(0, 0),
	    new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));

	setModal(true);
	setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
	label.setForeground(new java.awt.Color(51, 153, 255));
	label.setText("Loading Information");
	label.setOpaque(false);

	progressBar.setOpaque(false);
	progressBar.setBorderPainted(false);
	progressBar.setStringPainted(true);

	Container c = makeContainer();
	setContentPane(c);
	c.setLayout(new GridBagLayout());

	java.awt.GridBagConstraints gridBagConstraints;
	gridBagConstraints = new java.awt.GridBagConstraints();
	gridBagConstraints.gridx = 0;
	gridBagConstraints.gridy = 1;
	gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
	gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
	gridBagConstraints.insets = new java.awt.Insets(0, 5, 0, 5);
	getContentPane().add(label, gridBagConstraints);

	gridBagConstraints = new java.awt.GridBagConstraints();
	gridBagConstraints.gridx = 0;
	gridBagConstraints.gridy = 2;
	gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
	gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
	gridBagConstraints.insets = new java.awt.Insets(2, 5, 8, 5);
	getContentPane().add(progressBar, gridBagConstraints);

	gridBagConstraints = new java.awt.GridBagConstraints();
	gridBagConstraints.gridx = 0;
	gridBagConstraints.gridy = 0;
	gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
	gridBagConstraints.weightx = 1.0;
	gridBagConstraints.weighty = 1.0;
	getContentPane().add(filler, gridBagConstraints);

	pack();
	SwingUtil.centerOnScreen(this);
    }

    private Container makeContainer() {
	java.net.URL url = getClass().getResource("/splash.png");
	Image image = new ImageIcon(url).getImage();
	JPanelBackground pnl = new JPanelBackground(image);
	return pnl;

    }
    private JProgressBar progressBar;
    private JLabel label;

    public JProgressBar getProgressBar() {
	return progressBar;
    }

    public JLabel getLabel() {
	return label;
    }

    class JPanelBackground
	extends JPanelImage {

	public JPanelBackground(Image image) {
	    super(image);
	    int w = image.getWidth(this);
	    int h = image.getHeight(this);
	    Dimension dim = new Dimension(w, h);
	    setPreferredSize(dim);
	    setSize(dim);
	}
    }

    public synchronized void setProgress(int percent, String information) {
	if (information != null) label.setText(information);
	progressBar.setValue(percent);
    }

    public synchronized void setProgress(int percent) {
	setProgress(percent, null);
    }

    public synchronized void setInformation(String information) {
	label.setText(information);
    }

    public final void startThread()
	throws IllegalThreadStateException {
	this.threadStart.start();
    }
    private final Thread threadStart = new Thread(new Runnable() {

	public void run() {
	    launch();
	    dispose();
	}
    }, "Thread-Splash");

    protected abstract void launch();
}
